#include "Record.h"
#include <iostream>
#include <string>
#include "Utils.h"

using std::string;

namespace duomai {
    namespace im {

        Record::Record(ColumnSet* pColumnSet) : m_pColumnSet(pColumnSet) {
            column_count_ = m_pColumnSet->getCount();
            m_Values.resize(column_count_);
        }
        Record::~Record() {
            //TODO
        }

        int Record::getColumnCount() const {
            return column_count_;
        }

        const string Record::toString() {
            string s;

            for (int column = 0; column < getColumnCount(); column++)
                if (Value* pValue = getValue(column))
                {
                    s += pValue->toString();
                    if (column < (getColumnCount() - 1))
                        s += "|";
                }

            return s;
        }

        const string Record::toSQL() {
            string s;

            for (int index = 0; index < m_pColumnSet->getCount(); index++)
            {
                if (Column* pColumn = m_pColumnSet->getByIndex(index))
                {
                    if (Value* value = getValue(pColumn->getColumnName()))
                    {
                        s += value->toSQL(pColumn->getColumnType());

                        if (index < (m_pColumnSet->getCount() - 1))
                            s += ", ";
                    }
                }
            }

            return s;
        }

        void Record::put(string key, string value) {
            Column* pColumn = getColumnByName(key);
            if (pColumn) {
                int index = pColumn->getIndex();
                Value* pValue = getValue(index);
                //pValue->setString(value);
                pValue->setValue(value, pColumn->getColumnType());
            }
        }

        void Record::put(string key, int64_t value) {
            Column* pColumn = getColumnByName(key);
            if (pColumn) {
                int index = pColumn->getIndex();
                Value* pValue = getValue(index);
                pValue->setValue(intToStr(value), pColumn->getColumnType());
            }
        }

        void Record::put(string key, double value) {
            Column* pColumn = getColumnByName(key);
            if (pColumn) {
                int index = pColumn->getIndex();
                Value* pValue = getValue(index);
                pValue->setValue(doubleToStr(value), pColumn->getColumnType());
            }
        }

        Column* Record::getColumnByName(string column_name) {
            if (Column* column = m_pColumnSet->getByName(column_name)) {
                return column;
            } else {
                std::cout << "Record::fieldByName: field '" + column_name + "' not found" << std::endl;
                return NULL;
            }
        }


        Value* Record::getValue(int column_index)
        {
            if ((column_index >= 0) && (column_index < (int)m_Values.size()))
                return &m_Values.at(column_index);

            return NULL;
        }


        Value* Record::getValue(string column_name) {

            if (Column* pColumn = m_pColumnSet->getByName(column_name))
                return getValue(pColumn->getIndex());

            return NULL;
        }

        const string Record::toSQLInsert(string table_name) {

            string s = "INSERT INTO " + table_name + " ";

            s += "(" + m_pColumnSet->toString() + ")";

            s += " values ";

            s += "(" + toSQL() + ")";

            return s;
        }
        const string Record::toSQLUpdate(string table_name, string where_condition) {

            string s = "UPDATE " + table_name + " SET ";

            for (int index = 0; index < m_pColumnSet->getCount(); index++)
            {
                if (Column* column = m_pColumnSet->getByIndex(index))
                {

                    if (Value* value = getValue(column->getColumnName()))
                    {
                        s += column->getColumnName() + "=" + value->toSQL(column->getColumnType());

                        if (index < (m_pColumnSet->getCount() - 1))
                            s += ", ";
                    }
                }
            }

            s += " " + where_condition;

            return s;
        }


    } /* im */ 

} /* duomai  */ 

